package com.smartum.mpr.server;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.smartum.mpr.client.services.NewsService;
import com.smartum.mpr.server.utils.ConnectionPropertyReader;
import com.smartum.mpr.server.utils.JSONHelper;
import com.smartum.mpr.shared.News;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 */
public class NewsServiceImpl extends RemoteServiceServlet implements NewsService {
    public static final String NO_PHOTO_NAME = "no-photobig.gif";

    public List<News> getImages() throws IOException {
        final JSONObject webRequestHeader = JSONHelper.buildImgRetrievalJSON(0, new Timestamp(0).getTime(),
                this.getThreadLocalRequest());

        final HttpURLConnection conn = JSONHelper.getHttpURLConnection(ConnectionPropertyReader.getNewsURL());
        try {
            conn.connect();
        } catch (IOException e) {
        }

        final String response = JSONHelper.proceedRequest(webRequestHeader, conn);

        return parseNewsResponse(response);
    }

    public List<News> addNews(String imageName, String title, String text) throws IOException {

        if (imageName == null || imageName.isEmpty()) {
            imageName = NO_PHOTO_NAME;
        }
        final String realPath = getServletContext().getRealPath("/");
        File uploadedFile = new File(realPath + "images" + File.separator + imageName);
        final JSONObject webRequestHeader = buildNewsAddJSON(title, text, this.getThreadLocalRequest());
        JSONHelper.sendRequestWithImage(uploadedFile, webRequestHeader);

        if (!NO_PHOTO_NAME.equals(imageName)) {
            uploadedFile.delete();
        }

        return getImages();
    }

    public List<News> delete(String newsId) throws IOException {
        final JSONObject webRequestHeader = buildDeleteNewsJSON(newsId,
                this.getThreadLocalRequest());

        final HttpURLConnection conn = JSONHelper.getHttpURLConnection(ConnectionPropertyReader.getDeleteNewsURL());
        try {
            conn.connect();
        } catch (IOException e) {
        }

        JSONHelper.proceedRequest(webRequestHeader, conn);

        return getImages();
    }

    public News updateNews(String newsId, String imageName, String newTitle, String newText) throws IOException {
        final JSONObject webRequestHeader = buildUpdateNewsJSON(newsId, newTitle, newText,
                this.getThreadLocalRequest());

        final HttpURLConnection conn = JSONHelper.getHttpURLConnection(ConnectionPropertyReader.getUpdateNewsURL());
        try {
            conn.connect();
        } catch (IOException e) {
        }

        JSONHelper.proceedRequest(webRequestHeader, conn);
        if (imageName != null) {

            final String realPath = getServletContext().getRealPath("/");
            File uploadedFile = new File(realPath + "images" + File.separator + imageName);

            final JSONObject updateImageHeader = buildUpdateNewsForPhotoJSON(newsId, this.getThreadLocalRequest());
            JSONHelper.sendRequestOnUpdateWithImage(uploadedFile, updateImageHeader);

            if (!NO_PHOTO_NAME.equals(imageName)) {
                uploadedFile.delete();
            }
        }

        final HttpSession session = this.getThreadLocalRequest().getSession(false);

        final Object authToken = session.getAttribute(JSONHelper.AUTH_TOKEN);
        final JSONObject getNewsByIdRequestHeader = JSONHelper.getWebRequestHeader(authToken);

        JSONObject requestObject = new JSONObject();
        requestObject.put("news_id", new Long(newsId));

        getNewsByIdRequestHeader.put("request", requestObject);

        final HttpURLConnection getNewsByIdConnection = JSONHelper.getHttpURLConnection(ConnectionPropertyReader.getNewsByIdURL());
        try {
            getNewsByIdConnection.connect();
        } catch (IOException e) {
        }

        final String response = JSONHelper.proceedRequest(webRequestHeader, getNewsByIdConnection);
        News result = null;
        try {
            JSONObject responseJSONAsArray = JSONHelper.getResponseJSON(response);
            result = getNewsFromJSON(responseJSONAsArray);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return result;
    }

    private JSONObject buildUpdateNewsJSON(String newsId, String newTitle, String newText, HttpServletRequest request) throws IOException {
        final HttpSession session = request.getSession(false);

        final Object authToken = session.getAttribute(JSONHelper.AUTH_TOKEN);
        final JSONObject webRequestHeader = JSONHelper.getWebRequestHeader(authToken);

        JSONObject requestObject = new JSONObject();
        requestObject.put("news_id", new Long(newsId));
        requestObject.put("news_title", newTitle);
        requestObject.put("news_text", newText);

        webRequestHeader.put("request", requestObject);
        return webRequestHeader;
    }

    private JSONObject buildUpdateNewsForPhotoJSON(String newsId, HttpServletRequest request) throws IOException {
        final HttpSession session = request.getSession(false);

        final Object authToken = session.getAttribute(JSONHelper.AUTH_TOKEN);
        final JSONObject webRequestHeader = JSONHelper.getWebRequestHeader(authToken);

        JSONObject requestObject = new JSONObject();
        requestObject.put("news_id", new Long(newsId));

        webRequestHeader.put("request", requestObject);
        return webRequestHeader;
    }

    public JSONObject buildDeleteNewsJSON(String newsId, HttpServletRequest request) throws IOException {

        final HttpSession session = request.getSession(false);

        final Object authToken = session.getAttribute(JSONHelper.AUTH_TOKEN);
        final JSONObject webRequestHeader = JSONHelper.getWebRequestHeader(authToken);

        JSONObject requestObject = new JSONObject();
        requestObject.put("news_id", new Long(newsId));

        webRequestHeader.put("request", requestObject);
        return webRequestHeader;
    }

    public static JSONObject buildNewsAddJSON(String title, String text, HttpServletRequest request) throws IOException {

        final HttpSession session = request.getSession(false);

        final Object authToken = session.getAttribute(JSONHelper.AUTH_TOKEN);
        final JSONObject webRequestHeader = JSONHelper.getWebRequestHeader(authToken);

        JSONObject requestObject = new JSONObject();
        requestObject.put("news_title", title);
        requestObject.put("news_text", text);

        webRequestHeader.put("request", requestObject);
        return webRequestHeader;
    }

    private List<News> parseNewsResponse(String response) {
        final List<News> result = new ArrayList<News>();

        final JSONArray responseJSON;
        try {
            final JSONObject mainNewsResponse = JSONHelper.getResponseJSON(response);
            final Long news_count = (Long) mainNewsResponse.get("news_count");

            final JSONParser jsonParser = new JSONParser();
            responseJSON = (JSONArray) mainNewsResponse.get("news");
            for (int i = 0; i < responseJSON.size(); i++) {
                final JSONObject jsonObject = (JSONObject) responseJSON.get(i);
                final News news = getNewsFromJSON(jsonObject);

                result.add(news);
            }
        } catch (ParseException e) {
        }

        return result;
    }

    private News getNewsFromJSON(JSONObject jsonObject) {
        final News news = new News();

        news.setId((Long) jsonObject.get(JSONHelper.NEWS_ID));
        news.setNewsTitle((String) jsonObject.get(JSONHelper.NEWS_TITLE));
        news.setNewsText((String) jsonObject.get(JSONHelper.NEWS_TEXT));

        final JSONObject images = (JSONObject) jsonObject.get(JSONHelper.NEWS_IMAGES);
        if (images != null) {
            news.setNewsImageUrl((String) images.get(JSONHelper.NEWS_IMAGE_URL));
            news.setNewsImageUrlLittle((String) images.get(JSONHelper.NEWS_IMAGE_URL_LITTLE));
        } else {
            news.setNewsImageUrl(NO_PHOTO_NAME);
            news.setNewsImageUrlLittle(NO_PHOTO_NAME);
        }
        return news;
    }
}
